package com.h2cloud.tree;

import java.util.Arrays;

/**
 * @author: wulongkai
 * @create: 2023-03-22 10:48
 **/
public class RangeQuery {

    private int[] tree;
    private int[] nums;
    private int n;
    private boolean isMax;

    public RangeQuery(int[] _nums, boolean _isMax) {
        this.isMax = _isMax;
        this.nums = _nums;
        this.n = _nums.length;
        this.tree = new int[n + 1];

        Arrays.fill(this.tree, isMax ? Integer.MIN_VALUE : Integer.MAX_VALUE);
        for (int index = 0; index < n; index++) {
            update(index + 1, nums[index]);
        }
    }

    private int lowbit(int x) {
        return x & -x;
    }

    private int MathCount(int a, int b) {
        return isMax ? Math.max(a, b) : Math.min(a, b);
    }

    // 更新数组下标
    private void updateNums(int index, int val) {
        update(index + 1, val);
        nums[index] = val;
    }

    // 向上更新 tree
    private void update(int index, int value) {
        while (index <= n) {
            tree[index] = MathCount(tree[index], value);
            index += lowbit(index);
        }
    }

    private int query(int left, int right) {
        left++;
        right++;
        int result = isMax ? Integer.MIN_VALUE : Integer.MAX_VALUE;
        while (right >= left) {
            if (right - lowbit(right) >= left) {
                result = MathCount(result, tree[right]);
                right -= lowbit(right);
            } else {
                result = MathCount(result, nums[right - 1]);
                right--;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] a = {3, 1, 2, 4, 6, 5, 9, 3};
        RangeQuery rmq = new RangeQuery(a, false);
        System.out.println("Arrays.toString(rmq.tree) = " + Arrays.toString(rmq.tree));

//        rmq.updateNums(3, 61);
        System.out.println("Arrays.toString(rmq.a) = " + Arrays.toString(rmq.nums) + " size = " + rmq.nums.length);
        System.out.println("Arrays.toString(rmq.tree) = " + Arrays.toString(rmq.tree));
        System.out.println(rmq.query(3, 7)); // Output: 6
//        System.out.println(rmq.query(8, 8)); // Output: 6

        int[] brr = {1, 2, 3, 4, 5, 6, 7, 8};
        for (int val : brr) {
            System.out.print(" " + rmq.lowbit(val));
        }
    }
}

